package com.icez.ball_ripple_progress_library

import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.animation.LinearInterpolator
import android.widget.ViewAnimator
import kotlin.math.min


class BallRippleProgressView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
    // 圆形的路径
    private val mCirclePath: Path = Path()

    // 圆形的半径
    private var mRadius = 0f

    // 进度的路径
    private var mProgressPath: Path = Path()

    // 进度百分比
    private var mProgress: Float = 0f

    // 进度的画笔
    private var mProgressPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)

    // 波的高度
    private var mWaveHeight: Float = 0f

    // 波的中间位置
    private var mWaveMiddleWidth = 0f

    // 波的数量
    private var mWaveNum: Int = 4

    // 圆形的直径
    private var mDiameter = 0f

    // 波的动画
    private var mWaveObjectAnimator: ObjectAnimator? = null

    // 进度的动画
    private var mProgressObjectAnimator: ObjectAnimator? = null

    // 波的偏移
    private var mWaveOffset: Float = 0f

    // 进度监听
    private var mOnProgressCallback:OnProgressCallback ?= null

    // 背景
    private var mBackground:Int = Color.RED

    // 波的一个动画时间
    private var mWaveAnimaDuration:Int = 0

    // 进度动画时间
    private var mProgressAnimaDuration:Int = 0

    init {

        val typedArray = context.obtainStyledAttributes(attrs,R.styleable.BallRippleProgressView)
        val progressColor = typedArray.getColor(R.styleable.BallRippleProgressView_progressColor,Color.YELLOW)
        mBackground = typedArray.getColor(R.styleable.BallRippleProgressView_circleBackground,Color.RED)
        mWaveHeight = typedArray.getDimension(R.styleable.BallRippleProgressView_waveHeight,20f)
        mWaveNum = typedArray.getInteger(R.styleable.BallRippleProgressView_waveNum,4)
        mWaveAnimaDuration = typedArray.getInteger(R.styleable.BallRippleProgressView_waveAnimaDuration,2000)
        mProgressAnimaDuration = typedArray.getInteger(R.styleable.BallRippleProgressView_progressAnimaDuration,2000)
        typedArray.recycle()

        mProgressPaint.color = progressColor
        mProgressPaint.style = Paint.Style.FILL
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        // 计算控件的宽度
        val width = Utils.instance.measureViewWidth(widthMeasureSpec, null)
        // 计算控件的高度
        val height = Utils.instance.measureViewHeight(heightMeasureSpec, null)
        // 获取宽度与高度最小值
        val minWidthOrHeight = min(width, height)
        if(minWidthOrHeight <= 0){
            throw Exception("请设置控件的宽度或者高度")
        }
        setMeasuredDimension(minWidthOrHeight, minWidthOrHeight)
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        mRadius = min(w, h) / 2f
        mDiameter = mRadius * 2
        mCirclePath.reset()
        mCirclePath.addCircle(w / 2f, h / 2f, mRadius, Path.Direction.CW)
        mWaveMiddleWidth = mDiameter / 4f / 2f


        mWaveObjectAnimator?.cancel()
        mWaveObjectAnimator = AnimatorUtil.instance.objectAnimator(
            this,
            type = AnimatorUtil.ObjectAnimatorType.CUSTOMPROPERTY,
            null,
            "waveOffset",
            {
                it.repeatCount = ValueAnimator.INFINITE
                it.interpolator = LinearInterpolator()
                it.duration = mWaveAnimaDuration.toLong()
            },
            {},
            0f,
            mDiameter
        )
        mWaveObjectAnimator?.start()


        mProgressObjectAnimator?.cancel()

        mProgressObjectAnimator = AnimatorUtil.instance.objectAnimator(
            this,
            type = AnimatorUtil.ObjectAnimatorType.CUSTOMPROPERTY,
            null,
            "progress",
            {
                it.interpolator = LinearInterpolator()
                it.duration = mProgressAnimaDuration.toLong()
            },
            {},
            0f,
            mProgress
        )
        mProgressObjectAnimator?.start()

    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        // 保存当前画布状态
        canvas?.save()

        // 裁剪路径
        canvas?.clipPath(mCirclePath)
        // 设置画布颜色
        canvas?.drawColor(mBackground)

        // 关闭圆形路径
        mCirclePath.close()

        // 重置进度路径
        mProgressPath.reset()

        // 进度路径
        mProgressPath.lineTo(-mDiameter + mWaveOffset, mDiameter - mDiameter * mProgress)

        for (i in 0 until mWaveNum) {
            mProgressPath.rQuadTo(mWaveMiddleWidth, -mWaveHeight, mWaveMiddleWidth * 2, 0f)
            mProgressPath.rQuadTo(mWaveMiddleWidth, mWaveHeight, mWaveMiddleWidth * 2, 0f)
        }

        mProgressPath.lineTo(mDiameter, mDiameter)
        mProgressPath.lineTo(0f, mDiameter)
        mProgressPath.close()

        // 绘制路径
        canvas?.drawPath(mProgressPath, mProgressPaint)

        // 绘制保存的状态
        canvas?.restore()
    }

    public fun setWaveOffset(mWaveOffset: Float) {
        this.mWaveOffset = mWaveOffset
        invalidate()
    }


    public fun setProgress(progress: Float) {
        if (progress > 1 || progress < 0) {
            throw Exception("progress 只能设置为零。")
        }
        this.mProgress = progress
        mOnProgressCallback?.progress(progress)
    }



    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        mWaveObjectAnimator?.cancel()
        mProgressObjectAnimator?.cancel()
    }

    public fun setOnProgressCallback(mOnProgressCallback:OnProgressCallback){
        this.mOnProgressCallback = mOnProgressCallback
    }

    interface OnProgressCallback{
        fun progress(currentProgress:Float)
    }
}